/**
 * 使用对象来存储收集响应式依赖
 * 对于对象的依赖管理
 * WeakMap---- obj==>map
 * map----- key==>Depend实例
 */
let activeReactiveFn = null

class Depend {
  constructor() {
    this.reactiveFns = new Set()
  }
  
  //添加依赖
  addDepend(fn) {
    this.reactiveFns.add(fn)
  }
  
  depend() {
    if (activeReactiveFn) {
      this.reactiveFns.add(activeReactiveFn)
    }
  }
  
  //遍历执行依赖
  notify() {
    this.reactiveFns.forEach(fn => fn())
  }
}

function watchFn(fn) {
  activeReactiveFn = fn
  //这里要执行一次，才能正确的收集依赖
  fn()
  activeReactiveFn = null
}

//获取obj-key对应的depend
const targetMap = new WeakMap()

function getDepends(obj, key) {
  //根据obj获取响应的map对象
  let objMap = targetMap.get(obj)
  if (!objMap) {
    //说明针对obj对象的依赖还未收集,为其新建一个map
    objMap = new Map
    targetMap.set(obj, objMap)
  }
  //根据key获取depend对象
  let depend = objMap.get(key)
  if (!depend) {
    depend = new Depend()
    objMap.set(key, depend)
  }
  return depend
}


function ddReactive(obj) {
  Object.keys(obj).forEach(key => {
    let value = obj[key]
    Object.defineProperty(obj, key, {
      get() {
        const dep = getDepends(obj, key)
        dep.depend()
        return value
      },
      set(v) {
        value = v
        const dep = getDepends(obj, key)
        dep.notify()
      }
    })
  })
  return obj
}

//生成响应式对象
const objProxy = ddReactive({
  name: 'l',
  age: 18
})


watchFn(function () {
  console.log(objProxy.name, '------')
  console.log(objProxy.name, '++++++')
})
watchFn(function () {
  console.log('my name is ' + objProxy.name)
})
watchFn(function () {
  console.log(objProxy.age)
})

objProxy.age = 190
